// ==UserScript==
// @name         Chat翻译
// @namespace    chat-translator
// @version      1.0.0
// @description  Chat翻译
// @author       manx98
// @license      MIT; https://opensource.org/licenses/MIT
// @require      https://cdn.bootcss.com/qs/6.7.0/qs.min.js
// @require      https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js
// @match        https://www.twitch.tv/*
// @match        https://play.afreecatv.com/*
// @icon         
// @run-at       document-start
// @grant GM_xmlhttpRequest
// @grant GM_download
// ==/UserScript==
$(function (){

    //百度翻译API
    let BAIDU_TRANSLATE_API={
        appid:"",//百度翻译API appid
        key:"",//百度翻译API Key
        to:"zh",//目的语言
        from:"auto",//目标语言
        sign:function (q,salt){
            return md5(this.appid+q+salt+this.key)
        },
        rand:function(){
            return Math.random().toString(36).slice(-6);
        },
        translate:function(q,callback){
            let st = Date.now();
            let data = {
                q,
                from:this.from,
                to:this.to,
                appid:this.appid,
                salt:st,
                sign:this.sign(q,st)
            }
            Requests.get("http://api.fanyi.baidu.com/api/trans/vip/translate?"+Qs.stringify(data)).then((result)=>{
                if(result.error_code!== undefined){
                    callback({
                        success:false,
                        result:result.error_msg
                    })
                }else{
                    callback({
                        success:true,
                        result:result.trans_result[0].dst
                    })
                }
            })
        }
    }

    //免费的Google Translate API,请求频率限制高(使用这个时不建议开启全局自动翻译)
    let GOOGLE_TRANSLATE_API={
        sl:'auto',//目的类型
        tl:'zh-CN',//目标语言
        translate:function(q,callback){
            let data = {
                client:"gtx",
                dt:"t",
                dj:1,
                ie:"UTF-8",
                sl:this.sl,
                tl:this.tl,
                q
            }
            Requests.get("http://translate.google.cn/translate_a/single?"+Qs.stringify(data)).then((res)=>{
                callback({
                    success:true,
                    result:res.sentences[0].trans
                })
            }).catch(()=>{
                callback({
                    success:false,
                    result:"请求失败！"
                })
            })
        }
    }

    //翻译设置
    const Config ={
        translateInterval: 1000, //翻译间隔(控制请求频率)
        api:GOOGLE_TRANSLATE_API, //使用的翻译API
        autoTranslate:false, //自动全局翻译,是否启用自动,容易触发接口频率限制
    }

    //用于存储不同页面翻译策略
    const TRANSLATE_MODEL={
        "www.twitch.tv":{
            getChatContainer(){
                return $('div[data-test-selector="chat-scrollable-area__message-container"]')
            },
            getChatMessageContainer(dom){
                return $(dom).find('span.text-fragment')
            }
        },
        "play.afreecatv.com":{
            getChatContainer(){
                return $('#chat_area')
            },
            getChatMessageContainer(dom){
                return $(dom).find('dd')
            }
        }
    }

    //简易的跨域请求封装
    const Requests = {
        request:function Requests(query){
            return new Promise((resolve, reject)=>{
                query.onload = function(res) {
                    if (res.status === 200) {
                        let text = res.responseText;
                        let json = JSON.parse(text);
                        resolve(json)
                    }else{
                        reject(res);
                    }
                }
                query.onerror = function(res){
                    reject(res)
                }
                GM_xmlhttpRequest(query);
            })
        },
        get:function(url){
            return this.request({
                method:"get",
                url:url
            })
        },
        post:function(url,data){
            return this.request({
                method:"post",
                url:url,
                data:data,
                headers:{ "Content-Type": "application/x-www-form-urlencoded" }
            })
        }
    }

    //获取Chat容器
    function getChatContainer(){
        return TRANSLATE_MODEL[window.location.host].getChatContainer();
    }

    //获取翻译内容
    function getChatMessage(content){
        let $chartsContainer = TRANSLATE_MODEL[window.location.host].getChatMessageContainer(content);
        if($chartsContainer.length>0)
        {
            if(Config.autoTranslate)
            {
                translateTasks.push($chartsContainer)
            }else{
                addTranslateButton($chartsContainer)
            }
        }
    }

    //华丽的分割
    const HR = `<div style="border-bottom: darkgray 1px solid"></div>`;

    //添加翻译按钮
    function addTranslateButton(target){
        let text = target.text();
        target.html(`${text}${HR}<button mark="my-button-mark" style="border: snow 1px solid;background-color: dodgerblue;width: 100%;color: white"><b>点击翻译</b></button>`)
        target.find('button[mark="my-button-mark"]').click(()=>{
            target.html(`${text}`);
            translate(target)
        })
    }

    //添加重试按钮
    function addRetryButton(target,text,message){
        target.html(`${text}${HR}<button mark="my-button-mark"><b style="border: snow 1px solid;background-color: wheat;width: 100%;color: red">${message}</b></button>"`)
        target.find('button[mark="my-button-mark"]').click(()=>{
            target.html(`${text}`);
            translate(target)
        })
    }

    //翻译指定对话框
    function translate(target){
        let text = target.text().trim();
        if(text.length === 0){
            return
        }
        target.html(`${text}${HR}<b style="color: dodgerblue">开始翻译</b>`)
        Config.api.translate(text,(result)=>{
            if(result.success){
                target.html(`${text}${HR}<b style="color: green">${result.result}</b>`)
            }else{
                addRetryButton(target,text,`翻译失败,点击重试：${result.result}`)
            }
            translateItem = undefined;
        })
    }

    //添加事件监听
    function addEventListener(dom){
        console.log(dom)
        dom.on('DOMNodeInserted',(e)=>{
            getChatMessage(e.target)
        })
    }

    //翻译任务队列
    const translateTasks = []
    //避免并发请求
    let translateItem = undefined;
    //初始化
    function init (dom){
        setInterval(()=>{
            if(translateTasks.length > 0 && !translateItem)
            {
                translateItem = translateTasks.shift()
                translate(translateItem)
            }
        },Config.autoTranslate)
        addEventListener(dom)
    }

    //循环检查对话框是否加载完毕
    function tryInit(){
        let t = setInterval(()=>{
            let $chats = getChatContainer();
            if($chats.length>0){
                init($chats)
                clearInterval(t)
            }
        },1000)
    }
    tryInit();
})
